<template>
  <div class="role-manage">
    <div class="query-form">
      <el-form :inline="true" ref="form" :model="queryForm">
        <el-form-item label="角色名称" prop="roleName">
          <el-input
            v-model="queryForm.roleName"
            placeholder="请输入角色名称"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="getRoleList">查询</el-button>
          <el-button @click="handleReset('form')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="base-table">
      <div class="action">
        <el-button type="primary" @click="handleAdd" v-has="'role-create'"
          >+创建</el-button
        >
      </div>
      <el-table :data="roleList">
        <el-table-column
          v-for="item in columns"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :formatter="item.formatter"
        >
        </el-table-column>
        <el-table-column label="操作" width="250">
          <template #default="scope">
            <el-button
              size="mini"
              @click="handleEdit(scope.row)"
              v-has="'role-edit'"
              >编辑</el-button
            >
            <el-button
              size="mini"
              type="primary"
              @click="handleOpenPermission(scope.row)"
              v-has="'role-setting'"
              >设置权限</el-button
            >
            <Modal
              title="确定要删除？"
              @handleDel="handleDel(scope.row._id)"
              v-has="'role-delete'"
            />
            <!-- <el-button
              size="mini"
              type="danger"
              @click="handleDel(scope.row._id)"
              >删除</el-button
            > -->
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        class="pagination"
        background
        layout="prev, pager, next"
        prev-text="上一页"
        next-text="下一页"
        :total="pager.total"
        :page-size="pager.pageSize"
        @current-change="handleCurrentChange"
      />
    </div>
    <el-dialog title="角色新增" v-model="showModal">
      <el-form
        ref="dialogForm"
        :model="roleForm"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            type="textraea"
            rows="2"
            v-model="roleForm.remark"
            placeholder="请输入备注"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleClose">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--权限弹框-->
    <el-dialog title="权限设置" v-model="showPermission">
      <el-form label-width="100px">
        <el-form-item label="角色名称">
          {{ curRoleName }}
        </el-form-item>
        <el-form-item label="选择权限">
          <el-tree
            ref="tree"
            :data="menuList"
            show-checkbox
            node-key="_id"
            default-expand-all
            :props="{ label: 'menuName' }"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showPermission = false">取消</el-button>
          <el-button type="primary" @click="handlePermissionSubmit"
            >确定</el-button
          >
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { getCurrentInstance, ref, reactive, toRaw } from 'vue';
import utils from '../utils/utils';
import Modal from '../components/Modal.vue';

const { proxy } = getCurrentInstance();
// 查询角色表单数据
const queryForm = reactive({
  roleName: '',
});
// 角色列表字段
const columns = reactive([
  { label: '角色名称', prop: 'roleName' },
  { label: '备注', prop: 'remark' },
  {
    label: '权限列表',
    prop: 'permissionList',
    width: 200,
    formatter(row, column, value) {
      let names = [];
      let list = value.halfCheckedKeys || [];
      list.map((key) => {
        let name = actionMap.value[key];
        if (key && name) names.push(name);
      });
      return names.join(',');
    },
  },
  {
    label: '创建时间',
    prop: 'createTime',
    width: 160,
    formatter(row, column, value) {
      return utils.formateDate(new Date(value));
    },
  },
  {
    label: '更新时间',
    prop: 'updateTime',
    width: 160,
    formatter(row, column, value) {
      return utils.formateDate(new Date(value));
    },
  },
]);
// 角色列表数据
const roleList = ref([]);
// 分页数据
const pager = reactive({
  total: 0,
  pageNum: 1,
  pageSize: 10,
});
// 角色弹框展示
const showModal = ref(false);
const action = ref('create');
// 角色操作表单数据
const roleForm = reactive({});
const rules = reactive({
  roleName: [
    {
      required: true,
      message: '请输入角色名称',
    },
  ],
});
// 权限展示
const showPermission = ref(false);
const curRoleId = ref('');
const curRoleName = ref('');
const menuList = ref([]);
// 菜单映射表
const actionMap = ref({});

// 初始化角色列表
const getRoleList = async () => {
  let params = { ...queryForm, ...pager };
  try {
    let { list, page } = await proxy.$api.getRoleList(params);
    roleList.value = list;
    pager.total = page.total;
  } catch (error) {
    throw new Error(error);
  }
};
// 初始化菜单列表
const getMenuList = async () => {
  try {
    let list = await proxy.$api.getMenuList();
    menuList.value = list;
    getActionMap(list);
  } catch (error) {
    throw new Error(error);
  }
};
// 权限列表
const getActionMap = (list) => {
  let acMap = {};
  const deep = (arr) => {
    while (arr.length) {
      let item = arr.pop();
      if (item.children && item.action) {
        acMap[item._id] = item.menuName;
      }
      if (item.children && !item.action) {
        deep(item.children);
      }
    }
  };
  deep(JSON.parse(JSON.stringify(list)));
  actionMap.value = acMap;
};
// 表单重置
const handleReset = (form) => {
  proxy.$refs[form].resetFields();
};
// 弹框关闭
const handleClose = () => {
  handleReset('dialogForm');
  showModal.value = false;
};
// 角色添加
const handleAdd = () => {
  action.value = 'create';
  showModal.value = true;
};
// 角色编辑
const handleEdit = (row) => {
  action.value = 'edit';
  showModal.value = true;
  proxy.$nextTick(() => {
    Object.assign(roleForm, {
      _id: row._id,
      roleName: row.roleName,
      remark: row.remark,
    });
  });
};
// 角色删除
const handleDel = async (_id) => {
  await proxy.$api.roleOperate({ _id, action: 'delete' });
  proxy.$message.success('删除成功');
  getRoleList();
};
// 角色提交
const handleSubmit = () => {
  proxy.$refs.dialogForm.validate(async (valid) => {
    if (valid) {
      let params = toRaw(roleForm);
      params.action = action.value;
      await proxy.$api.roleOperate(params);
      showModal.value = false;
      proxy.$message.success('创建成功');
      handleReset('dialogForm');
      getRoleList();
    }
  });
};
// 分页
const handleCurrentChange = (current) => {
  pager.pageNum = current;
  getRoleList();
};
// 设置权限弹框
const handleOpenPermission = (row) => {
  curRoleId.value = row._id;
  curRoleName.value = row.roleName;
  showPermission.value = true;
  let { checkedKeys } = row.permissionList;
  proxy.$nextTick(() => {
    // 已有的角色权限设置为选中状态
    proxy.$refs.tree.setCheckedKeys(checkedKeys);
  });
};
// 设置权限弹框提交
const handlePermissionSubmit = async () => {
  let nodes = proxy.$refs.tree.getCheckedNodes(); // 获取选中末节点
  let halfKeys = proxy.$refs.tree.getHalfCheckedKeys(); // 获取选中末节点的父节点
  let checkedKeys = []; // 每个选中的按钮
  let parentKeys = []; // 每个选中的菜单
  nodes.map((node) => {
    if (!node.children) {
      checkedKeys.push(node._id);
    } else {
      parentKeys.push(node._id);
    }
  });
  let params = {
    _id: curRoleId.value,
    permissionList: {
      checkedKeys, // 选中的子菜单
      halfCheckedKeys: parentKeys.concat(halfKeys), // 半选中的父菜单
    },
  };
  let res = await proxy.$api.updatePermission(params);
  showPermission.value = false;
  proxy.$message.success('设置成功');
  getRoleList();
};

getRoleList();
getMenuList();
</script>

<style lang="scss"></style>
